package com.cz.android.gif.sample.visualize;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.cz.android.gif.GifDecoder;
import com.cz.android.gif.reader.Reader;
import com.cz.android.gif.sample.R;
import com.cz.android.gif.sample.visualize.view.GifBlockData;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;

/**
 * Created by cz on 2020/9/19.
 * The GIF data block parser abstraction.
 * We use this abstraction to handle all the different parts of the gif file.
 *
 */
public abstract class GifBlockParser {
    public static final String TAG="GifBlockParser";
    public static final int ATTRIBUTE_COLUMN_SIZE=4;

    public static final int HEADER=0x00;
    public static final int LOGICAL_SCREEN_DESCRIPTOR=0x01;
    public static final int IMAGE_INSPECTOR=0x02;
    public static final int IMAGE_DATA_BLOCK=0x03;
    public static final int APPLICATION_EXTENSION=0x04;
    public static final int COMMENT_EXTENSION=0x05;
    public static final int GRAPHICS_CONTROL_EXTENSION=0x06;
    public static final int PLAIN_TEXT_EXTENSION=0x07;
    public static final int COLOR_TABLE_EXTENSION=0x08;
    public static final int TERMINATOR=0x09;
    /**
     * Determine if you want to handle this data block.
     * @param identifier
     * @return
     */
    public abstract boolean applyIdentifier(int identifier);
    /**
     * Print the block information.
     */
    public abstract void printBlockMessage();

    /**
     * Read the GIF data block information.
     * @param reader
     * @return
     * @throws IOException
     */
    public abstract GifBlockData readBlock(Reader reader) throws IOException;

    /**
     * Create a view that display this data block's information.
     * @param context
     * @return
     */
    public abstract View onCreateView(Context context,LayoutInflater layoutInflater,ViewGroup parent);

    /**
     * If the method {@link #applyIdentifier(int)} return true. Then you start process the data.
     * Here We ask for a view generated by the data block.
     *
     * @param context
     * @param layout
     * @return
     */
    public abstract void onBindView(Context context, GifDecoder decoder,View layout, GifBlockData blockData, ByteBuffer byteBuffer) throws IOException;

    /**
     * If we have the following block parser. The processor will handle this and get more information.
     * We use this method to return more block parser that related to this block parser.
     * @return
     */
    public List<GifBlockParser> followingBlockParser(){
        return null;
    }

    /**
     * Add a attribute view to the attribute list.
     * All the block data have some different attributes.
     * Like the header we will put the version of the file.
     * @param leftAttributeName
     * @param leftAttributeValue
     * @param rightAttributeName
     * @param rightAttributeValue
     */
    public void initAttributeView(View layout,
                                 String leftAttributeName, String leftAttributeValue, String rightAttributeName, String rightAttributeValue) {
        TextView leftAttributeNameView = layout.findViewById(R.id.leftAttributeName);
        TextView leftAttributeValueView = layout.findViewById(R.id.leftAttributeValue);
        TextView rightAttributeNameView = layout.findViewById(R.id.rightAttributeName);
        TextView rightAttributeValueView = layout.findViewById(R.id.rightAttributeValue);
        if(null==leftAttributeName){
            leftAttributeNameView.setVisibility(View.INVISIBLE);
            leftAttributeValueView.setVisibility(View.INVISIBLE);
        } else {
            leftAttributeNameView.setText(leftAttributeName);
            leftAttributeValueView.setText(leftAttributeValue);
        }
        if(null==rightAttributeNameView){
            rightAttributeNameView.setVisibility(View.INVISIBLE);
            rightAttributeValueView.setVisibility(View.INVISIBLE);
        } else {
            rightAttributeNameView.setText(rightAttributeName);
            rightAttributeValueView.setText(rightAttributeValue);
        }
    }

    /**
     * Add a attribute view to the attribute list.
     * All the block data have some different attributes.
     * Like the header we will put the version of the file.
     * @param layoutInflater
     * @param attributeLayout
     * @param leftAttributeName
     * @param leftAttributeValue
     * @param rightAttributeName
     * @param rightAttributeValue
     */
    public void addAttributeView(LayoutInflater layoutInflater, LinearLayout attributeLayout,
                          String leftAttributeName, String leftAttributeValue, String rightAttributeName, String rightAttributeValue) {
        View layout = layoutInflater.inflate(R.layout.gif_attribute_layout, attributeLayout, false);
        initAttributeView(layout,leftAttributeName,leftAttributeValue,rightAttributeName,rightAttributeValue);
        attributeLayout.addView(layout, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    public CharSequence padStart(CharSequence text,int length,char padChar){
        if (length < 0)
            throw new IllegalArgumentException("Desired length $length is less than zero.");
        if (length <= text.length())
            return text.subSequence(0, text.length());

        StringBuilder sb = new StringBuilder(length);
        for (int i=1;i<=(length - text.length());i++)
            sb.append(padChar);
        sb.append(text);
        return sb;
    }
}
